package com.youlu.campus.service.h5.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.component.SmsUtil;
import com.youlu.campus.entity.H5UserPO;
import com.youlu.campus.entity.UserOtherInfo;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.VO.req.CheckMobileVO;
import com.youlu.campus.entity.domain.UserResponse;
import com.youlu.campus.entity.dto.sms.SmsBaseInfoDTO;
import com.youlu.campus.service.h5.H5UserPOService;
import com.youlu.campus.service.sms.SmsServerService;
import com.youlu.campus.service.system.SystemIdService;
import com.youlu.campus.service.visitor.VisitorUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

@Slf4j
@Service
public class H5UserPOServiceImpl implements H5UserPOService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private VisitorUserService visitorUserService;
    @Autowired
    private SmsUtil smsUtil;
    @Autowired
    private SystemIdService systemIdService;
    @Autowired
    private SmsServerService smsServerService;

    @Override
    public UserResponse codeLogin(CheckMobileVO req) {
        log.info(":>>> 开始手机验证码登陆:{}", JSON.toJSONString(req));
        if (Objects.isNull(req) || StringUtils.isBlank(req.getMobile()) || StringUtils.isBlank(req.getCode())) {
            log.error(":>>> 手机验证码登陆参数错误");
            throw new BusinessException("手机验证码登陆参数错误");
        }
        SmsBaseInfoDTO dto = SmsBaseInfoDTO.builder().phone(req.getMobile()).code(req.getCode()).build();
        Pair<Boolean, String> re = smsServerService.checkVerifyCode(dto);
        if(!re.getLeft()){
            throw new BusinessException(re.getRight());
        }
        log.info(":>>> 手机号:{},验证码结果:{}", req.getMobile(), JSON.toJSONString(re));
        UserPO userPO = visitorUserService.find(req.getMobile(), Boolean.TRUE);
        Date date = new Date();
        String openId = "";
        if (Objects.isNull(userPO)) {
            log.info(":>>> 手机号:{} 账户信息为空", req.getMobile());
            openId = "h5-" + req.getMobile();
            userPO = visitorUserService.getUserByOpenId(openId);
            if (Objects.isNull(userPO)) {
                log.error(":>>> h5用户通过openId查询不到", openId);
                userPO = new UserPO();
                userPO.setId(null);
                userPO.setOpenId(openId);
                userPO.setCreatedTime(new Date());
                userPO.setCheckedMobile(true);
                userPO.setMobile(req.getMobile());
                userPO.setAppId(req.getAppId());
                userPO.setCheckedMobileTime(date);
                userPO = mongoTemplate.insert(userPO);
            }
        }
        Query queryAppUser = new Query().addCriteria(Criteria.where("openId").is(openId));
        H5UserPO appUserPO = mongoTemplate.findOne(queryAppUser, H5UserPO.class);
        if (Objects.isNull(appUserPO)) {
            log.error(":>>> 账户:{} 的h5用户不存在", userPO.getId());
            openId = "h5-" + req.getMobile();
            appUserPO = new H5UserPO();
            appUserPO.setId(null);
            appUserPO.setAccountInfoId(userPO.getId());
            appUserPO.setCheckedMobile(true);
            appUserPO.setOpenId(openId);
            appUserPO.setCreatedTime(date);
            appUserPO.setCheckedMobile(true);
            appUserPO.setMobile(req.getMobile());
            appUserPO.setCheckedMobileTime(date);
            appUserPO.setAppId(req.getAppId());
            appUserPO.setLoginTime(date);
            appUserPO = mongoTemplate.insert(appUserPO);
            log.info(":>>> app验证码登陆,手机号:{} 账户信息为空,创建H5用户:{}", req.getMobile(), openId);
        }
        openId = appUserPO.getOpenId();
        UserResponse userResponse = new UserResponse();
        userResponse.setOpenId(openId);
//        userResponse.setToken(WebTokenUtils.signToken(openId));
        userResponse.setAuthorized(false);
        return userResponse;
    }

    @Override
    public H5UserPO findByOpenId(String openId) {
        log.info(":>>> 开始查找H5用户信息:{}", openId);
        Query query = new Query().addCriteria(Criteria.where("openId").is(openId));
        H5UserPO userPO = mongoTemplate.findOne(query, H5UserPO.class);
        return userPO;
    }

    @Async
    @Override
    public void updateOtherInfo(UserOtherInfo u) {
        if (Objects.isNull(u) || StringUtils.isBlank(u.getUserId())) {
            log.error(":>>> 修改用户其他信息参数错误");
            return;
        }
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(u.getUserId()));
        Update up = new Update();
        boolean doIt = false;
        if (StringUtils.isNotBlank(u.getNickName())) {
            up.set("nickName", u.getNickName());
            doIt = true;
        }
        if (StringUtils.isNotBlank(u.getAvatarUrl())) {
            up.set("avatarUrl", u.getAvatarUrl());
            doIt = true;
        }
        if (doIt) {
            up.set("updatedTime", new Date());
            UpdateResult updateResult = mongoTemplate.updateMulti(query, up, H5UserPO.class);
            log.info(":>>> 修改纯H5用户信息结果:{},{}", u.getUserId(), updateResult.getModifiedCount());
        }

    }
}
